package com.yangran.config;

import com.yangran.service.PushService;
import com.yangran.strategy.factory.MessageHandlerFactory;
import com.yangran.strategy.factory.MessageHandlerStrategy;
import com.yangran.vo.MsgVo;
import com.yangran.vo.MyFacts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.api.RulesEngineParameters;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.core.RuleBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 规则引擎配置类
 * @author lishan
 * @date 2023/12/19
 */
@Configuration
//@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RuleEngineConfig {

    @Autowired
    private PushService pushService;

    @Autowired
    private MessageHandlerFactory messageHandlerFactory;

    /**
     * 定义规则引擎 todo：可按照业务定制规则引擎，就是别名多实例注入
     * DefaultRulesEngine：根据规则的自然顺序(默认为优先级)应用规则。
     * InferenceRulesEngine：在已知的事实上不断地应用规则，直到没有更多的规则可用。
     *
     * @return
     */
    @Bean
    public RulesEngine getRulesEngine() {
        RulesEngineParameters parameters = new RulesEngineParameters()
                .skipOnFirstAppliedRule(true) // 当一个规则成功应用时，跳过余下的规则
                .skipOnFirstFailedRule(true) // 当一个规则失败时，跳过余下的规则
                .skipOnFirstNonTriggeredRule(true); // 当一个规则未触发时，跳过余下的规则
        return new DefaultRulesEngine(parameters);
    }


    /**
     * 注册规则
     *
     * @return
     */
    @Bean
    //@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Rules getRules() {

        Rules rules = new Rules();

        Rule rule1 = new RuleBuilder()
                .name("myRule01")
                .description("myRuleDescription")
                .priority(1)
                .when(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    MsgVo msg = (MsgVo) myFacts.get("msg");
                    return msg.getVersion().equals(1);
                })
                .then(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    List<MessageHandlerStrategy> handlerList = myFacts.getHandlerList();
                    if (CollectionUtils.isEmpty(handlerList)){
                        ArrayList<MessageHandlerStrategy> messageHandlerStrategies = new ArrayList<>();
                        messageHandlerStrategies.add(messageHandlerFactory.getHandler("wechatMessageHandler"));
                        myFacts.setHandlerList(messageHandlerStrategies);
                    }else {
                        handlerList.add(messageHandlerFactory.getHandler("wechatMessageHandler"));
                    }
                    System.out.println("myRule01 校验通过");})
                .build();

        Rule rule2 = new RuleBuilder()
                .name("myRule02")
                .description("myRuleDescription")
                .priority(2)
                .when(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    MsgVo msg = (MsgVo) myFacts.get("msg");
                    return msg.getVersion().equals(2);
                })
                .then(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    List<MessageHandlerStrategy> handlerList = myFacts.getHandlerList();
                    if (CollectionUtils.isEmpty(handlerList)){
                        ArrayList<MessageHandlerStrategy> messageHandlerStrategies = new ArrayList<>();
                        messageHandlerStrategies.add(messageHandlerFactory.getHandler("feiShuMessageHandler"));
                        myFacts.setHandlerList(messageHandlerStrategies);
                    }else {
                        handlerList.add(messageHandlerFactory.getHandler("feiShuMessageHandler"));
                    }
                    System.out.println("myRule02 校验通过");
                })
                .build();

        Rule rule3 = new RuleBuilder()
                .name("myRule03")
                .description("myRuleDescription")
                .priority(3)
                .when(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    MsgVo msg = (MsgVo) myFacts.get("msg");
                    return msg.getVersion().equals(3);
                })
                .then(facts -> {
                    MyFacts myFacts = (MyFacts) facts;
                    MsgVo msg = (MsgVo) myFacts.get("msg");
                    pushService.push(msg.getVersion());
                    System.out.println("myRule03 校验通过");
                })
                .build();
        rules.register(rule1);
        rules.register(rule2);
        rules.register(rule3);

        return rules;
    }
}
